#include <sys/stat.h>
#include <sstream>
#include <cstdio>
#include <iostream>

#include "fp_buf.hpp"
#include "media_probe.hpp"


static std::string locate_ffprobe() {
    char* ffprobe = getenv("FFPROBE");
    if (ffprobe != nullptr) {
        struct stat stat_buf;
        int stat_error = stat(ffprobe, &stat_buf);
        if (stat_error == 0) {
            return std::string(ffprobe);
        }
    }
    // std::string merge_path = get_self_pathname();
    // std::cout << "merge_path=" << merge_path << std::endl;
    // auto last_slash = merge_path.rfind("/");
    // if (last_slash != std::string::npos) {
    //     merge_path = merge_path.substr(0, last_slash + 1);
    // }
    // merge_path += "ffprobe";

    return "/usr/bin/ffprobe";
}

static const std::string exec_probe(const std::ostringstream& w) {
    std::cout << w.str() << std::endl;
    fp_buf fb(popen(w.str().c_str(), "r"));
    std::istream in(&fb);
    std::string ffprobe_json_string;
    for (std::string line; std::getline(in, line); ) {
        ffprobe_json_string += line;
    }

    std::cout << "probe json: " << ffprobe_json_string << std::endl;
    return ffprobe_json_string;
} 

media_probe::media_probe() {
    _probe_path = locate_ffprobe();
}

media_probe::~media_probe() {
}

const std::string media_probe::readMediaInfo2Json(const std::string& mediaFile) {
    if(mediaFile.empty()) {
        return "N/A";
    }

    std::ostringstream w;
    w << _probe_path << " -hide_banner -show_entries format=duration:stream=index,codec_type,width,height,sample_rate,channels,channel_layout -of json=compact=1 " << mediaFile;
    // WRITER_INFO("ffprobe:", FMT().v(_media_file));  
    return exec_probe(w);
}

const std::string media_probe::readMediaDuration(const std::string& mediaFile) {
    if(mediaFile.empty()) {
        return "N/A";
    }

    std::ostringstream w;
    w << _probe_path << " -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " << mediaFile;
    // WRITER_INFO("ffprobe:", FMT().v(_media_file));  
    return exec_probe(w);
}

int media_probe::writeMediaInfoToFile(const std::string& mediaFile, const std::string& rtcName, const std::string& writeFilePath) {
    if(mediaFile.empty() || writeFilePath.empty()) {
        return -1;
    }

    std::string outPath = writeFilePath;
    std::string fileName = rtcName + ".ffprobe.json";
    struct stat s;
    if ( stat ( outPath.c_str(), &s ) != 0 || !(s.st_mode & S_IFDIR)) {
        return -2;
    } 

    std::string duration = readMediaDuration(mediaFile);
    if(duration == "N/A" || duration.empty()) {
        return -3;
    }

    //去除尾部空格
    outPath.erase(outPath.find_last_not_of(" ") + 1);
    if(outPath[outPath.size() - 1] != '/') {
        outPath += '/';
    }
    outPath += fileName;

    FILE *fp = fopen(outPath.c_str(), "w");
    if(!fp) {
        return -4;
    }

    std::ostringstream json;
    json << "{" << "\"duration\"" << ":" << duration << "}";


    fwrite(json.str().c_str(), 1, json.str().size(), fp);

    fclose(fp);
    fp = nullptr;

    return 0;
}